<?php

class WechatApi {
    private $api_url = 'https://qyapi.weixin.qq.com/cgi-bin/';   //企业微信接口url
    private $api_name = '';   //接口名
    private $access_token = '';
    private $req_data = array();
    private $req_type = 'get';
    private $app_type = '';  //应用类型
    private $app_id = '';  //应用app_id

    public function __construct($app_type = '') {
        if (!empty($app_type) && !in_array($app_type, array('image','video'))) {
            throw new CException('非法的应用类型');
        }
        $this->app_type = $app_type;
        $this->access_token = $this->getAccessToken();
    }

    /**
     * 获取票据(access_token)并缓存
     * @param $app_id string 应用id，如果为空就获取企业级别token
     * @return string 票据
    */
    private function getAccessToken() {
        $wechat_config = Yii::app()->params['wechat'];
        if (empty($wechat_config['corpid'])) {
            throw new CException('企业Id未配置');
        }
        $corpid = $wechat_config['corpid'];
        $cache_key = 'token_';   //缓存key
        if (!empty($this->app_type)) {
            //如果是应用级别的就获取应用级别票据
            $app_type = $this->app_type;
            if (empty($wechat_config['app'][$app_type]['AgentId']) || empty($wechat_config['app'][$app_type]['Secret'])) {
                throw new CException('应用参数未配置');
            }
            $this->app_id = $wechat_config['app'][$app_type]['AgentId'];
            $cache_key .= $this->app_id ;
            $corpsecret = $wechat_config['app'][$app_type]['Secret'];
        } else {
            if (empty($wechat_config['corpsecret'])) {
                throw new CException('管理组的凭证密钥未配置');
            }
            $cache_key .= $corpid;
            $corpsecret = $wechat_config['corpsecret'];
        }
        $access_token = Yii::app()->cache->get($cache_key);
        if ($access_token !== false) {
            return $access_token;
        }
        $this->req_data = array(
            'corpid' => $corpid,
            'corpsecret' => $corpsecret,
        );
        $this->api_name = 'gettoken?';
        $result = $this->fetch_curl();
        if ($result['errcode'] == 0 && $result['access_token']) {
            Yii::app()->cache->set($cache_key, $result['access_token'], 7000); //缓存近两个小时,因为token有效期是2小时
            return $result['access_token'];
        }
        throw new Exception($result['errmsg']);
    }

    /**
     * 获取部门信息
     * @param $id int 部门id
     * @return array 部门信息
    */
    public function getDepartment($id = 0) {
        $this->api_name = 'department/list';
        if (empty($id)) {
            $this->req_data = array(
                'id' => $id
            );
        }
        $result = $this->fetch_curl();
        return $result;
    }

    /**
     * 获取部门成员信息(简要信息)
     * 默认获取一级部门的所有成员
     * @param $pid int 部门id
     * @return array 部门成员信息
    **/
    public function getSimpleUser($pid = 1) {
        $this->api_name = 'user/simplelist';
        $this->req_data = array(
            'department_id' => $pid,
            'fetch_child' => 1,
        );
        $result = $this->fetch_curl();
        return $result;
    }

    /**
     * 获取部门成员信息(详细信息)
     * 默认获取一级部门的所有成员
     * @param $pid int 部门id
     * @return array 部门成员信息
     **/
    public function getDetailUser($pid = 1) {
        $this->api_name = 'user/list';
        $this->req_data = array(
            'department_id' => $pid,
            'fetch_child' => 1,
        );
        $result = $this->fetch_curl();
        return $result;
    }

    /**
     * 根据code获取用户信息
     * @param $code string OAuth授权后微信返回的code
     * @return array 用户信息
    */
    public function getUserByCode($code) {
        $this->api_name = 'user/getuserinfo';
        $this->req_data = array(
            'code' => $code
        );
        $result = $this->fetch_curl();
        return $result;
    }

    /**
     * 生成微信应用菜单
    */
    public function makeMenu($menu_data) {
        $this->api_name = 'menu/create';
        $this->req_type = 'post';
        $this->req_data = json_encode($menu_data);
        $result = $this->fetch_curl();
        return $result;
    }

    /**
     * 获取微信应用
    */
    public function getApp() {
        $this->api_name = 'agent/list';
        $result = $this->fetch_curl();
        return $result;
    }

    private function fetch_curl() {
        $url = $this->api_url . $this->api_name;
        $opt = array(
            CURLOPT_TIMEOUT => 10,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_SSL_VERIFYHOST => 0,
            CURLOPT_SSL_VERIFYPEER => false,
        );
        if (strpos($this->api_name, 'gettoken') === false) {
            $url .= '?access_token=' . $this->access_token;
            if (!empty($this->app_id)) {
                $url .= '&agentid='.$this->app_id;
            }
        }
        if ($this->req_type === 'get' && !empty($this->req_data)) {
            $url .= '&'.http_build_query($this->req_data);
        } else {
            $opt[CURLOPT_POST] = true;
            $opt[CURLOPT_POSTFIELDS] = $this->req_data;
        }
        $opt[CURLOPT_URL] = $url;

        $ch = curl_init();
        foreach($opt as $k => $v ){
            curl_setopt($ch, $k, $v );
        }

        $content = curl_exec($ch);

        return json_decode($content, true);
    }
}